<!-- 表格组件 -->
<template>
  <div class="page_table">
    <base-table :table-data="tableDataList" v-model:page="pagination" :total="total" :table-config="tableConfig"
      @selectionChange="handleSelectionChange">
      <template #header="{ row }">
        <el-popconfirm title="确定要删除?" @confirm="handleDel(null)"
          v-if="tableConfig?.showSelection && isPerMap.get('delete')">
          <template #reference>
            <el-button type="danger" size="small" :disabled="!ids.length">批量删除
            </el-button>
          </template>
        </el-popconfirm>
        <el-button type="success" size="small" v-if="isPerMap.get('create')" @click="handleCreateOrEdit(null)">添加
        </el-button>
        <el-button type="success" ype="success" v-if="isPerMap.get('import')" size="small" @click="handleImport">
          导入</el-button>
        <el-button type="success" v-if="isPerMap.get('export')" size="small" @click="handleExport">
          导出</el-button>
      </template>
      <template #status="{ row }">
        <el-button :type="row.status ? 'success' : 'danger'" size="mini" plain>
          {{ row.status ? "启用" : '禁用' }}
        </el-button>
      </template>
      <template #handle="{ row }">
        <el-button type="text" icon="el-icon-edit" v-if="isPerMap.get('update')" size="mini"
          @click="handleCreateOrEdit(row)">
          修改</el-button>
        <el-popconfirm title="确定要删除此条记录?" @confirm="handleDel(row)" v-if="isPerMap.get('delete')">
          <template #reference>
            <el-button type="text" icon="el-icon-delete" size="mini">
              删除</el-button>
          </template>
        </el-popconfirm>
        <slot name="password" :row="row"></slot>
        <slot name="uploadAvatar" :row="row"></slot>
      </template>
      <!--动态设置插槽 -->
      <template v-for="item in dynamicSlotName" :key="item.slotName" #[item.slotName]="scope">
        <template v-if="item.slotName">
          <slot :name="item.slotName" :row="scope.row"></slot>
        </template>
      </template>
    </base-table>
  </div>
</template>
<script setup lang='ts' >
import { computed, ref, watchEffect, reactive } from 'vue'
import { useStore } from "@/store/index"

import type { PropType } from "vue"
import type { ITableConfig, IPagination } from "../types/index"
import { usePermission } from "@/hooks/index"
const store = useStore()
const props = defineProps({
  tableConfig: {
    type: Object as PropType<ITableConfig>,
    required: true
  },
  pageName: {
    type: String,
    required: true
  }
})
const emit = defineEmits(['createOrEdit', 'exportData', 'importData', 'deleteMenu'])


let pagination = ref<IPagination>({
  currentPage: 1,
  pageSize: 10,

})
// 处理按钮权限 配置映射关系
let perArr = ['create', 'update', 'delete', 'query', 'import', 'export']
let isPerMap = new Map<string, boolean>()
for (const element of perArr) {
  isPerMap.set(element, usePermission(props.pageName, element, store))
}



// 1. 数据改变和初次加载  获取对应的数据

const getTableDataListDispatch = (searchKeywords?: object) => {
  // console.log(searchKeywords);

  // 有查询权限 才发送网络请求
  if (!isPerMap.get('query')) return false
  let queryInfo = {
    currentPage: pagination.value.currentPage,
    pageSize: pagination.value.pageSize,
  }
  if (searchKeywords) {
    for (const key in searchKeywords) {

      let element = searchKeywords[key]
      // 去除所有搜索条件的前后空格
      if (typeof searchKeywords[key] == 'string') {
        searchKeywords[key] = searchKeywords[key].trim()
      }
      // 去除无效字段
      if (key != 'status' && element === '') {
        delete searchKeywords[key]
      }

    }
    // 查询数据拼接
    queryInfo['otherWhere'] = { ...searchKeywords }
  }
  // 保存搜索条件 保证数据的统一 删除某一数据后依然展示符合上次搜索条件的数据
  store.commit('saveQueryInfo', { ...queryInfo, ...pagination.value })
  store.dispatch(`${props.pageName}/${props.pageName}ListAction`,  { queryInfo} )

}
// 监听底部 分页数据变换
watchEffect(() => {
  pagination
  getTableDataListDispatch()
})
/// 3. 从vuex 中获取 对应的数据 传给 table组件渲染
const tableDataList = computed(() => store.state[props.pageName][`${props.pageName}List`].rows)
let total = computed(() => store.state[props.pageName][`${props.pageName}List`].count)
// 4. 设置动态插槽 插槽的权限交给组件
const propsSlotNameData = props.tableConfig?.propsList ?? []
const publicSlotName = ['status', 'handle']
const dynamicSlotName = propsSlotNameData?.filter(item => {
  if (publicSlotName.includes(item.slotName)) return false
  return true
})

let ids = ref<Array<number>>([])
// 获取批量删除数据的id
const handleSelectionChange = (selection: any[]) => {
  if (selection.length) {
    ids.value = []
    selection.forEach(item => ids.value.push(item.id))
  } else {
    ids.value = []
  }
  ids.value = [...new Set(ids.value)]

}
//删除按钮事件
const handleDel = (row: any = null) => {
  if (!isPerMap.get('delete')) return false

  if (props.pageName == 'menu') {
    emit('deleteMenu', row)
  } else {
    if (row) {
      store.dispatch(`${props.pageName}/${props.pageName}DelAllAction`, { ids: [row.id] })
    } else {
      store.dispatch(`${props.pageName}/${props.pageName}DelAllAction`, { ids: ids.value })
    }
  }




}

// 处理 添加/修改事件
const handleCreateOrEdit = (row: any = null) => {
  emit('createOrEdit', row)
}

// 处理导入 事件

const handleImport = () => {

  emit('importData')
}
// 处理导出事件
const handleExport = () => {
  emit('exportData')

}


// 导出组件的方法
defineExpose({
  getTableDataListDispatch,
})


</script>
<style lang='less' scoped>
.page_table {
  padding: 20px;
}
</style>
